﻿/* 2013/6/10 */
using System;
using System.Collections.Generic;
using System.Text;

namespace Cosmos.IO.FileSystemPath.Searcher
{
    /// <summary>
    /// Factory class of file path searcher.
    /// </summary>
    public static class FilePathSearcherFactory
    {
        private const string ExactSearcherClassName = "Exact";
        private const string ExactSearcherDisplayName = "准确匹配";
        private const string FuzzySearcherClassName = "Fuzzy";
        private const string FuzzySearcherDisplayName = "模糊匹配";
        private const string SubstringSearcherClassName = "Substring";
        private const string SubstringSearcherDisplayName = "包含子串";
        private const string ExtensionSearcherClassName = "Extension";
        private const string ExtensionSearcherDisplayName = "扩展名";
        private const string RegexSearcherClassName = "Regex";
        private const string RegexSearcherDisplayName = "正则表达式";

        private static SearcherName[] _searcherNames = new SearcherName[]{
            new SearcherName(ExactSearcherClassName, ExactSearcherDisplayName),
            new SearcherName(FuzzySearcherClassName, FuzzySearcherDisplayName),
            new SearcherName(SubstringSearcherClassName, SubstringSearcherDisplayName),
            new SearcherName(ExtensionSearcherClassName, ExtensionSearcherDisplayName),
            new SearcherName(RegexSearcherClassName, RegexSearcherDisplayName)
        };

        /// <summary>
        /// Creates an instance of default file path searcher class.
        /// </summary>
        /// <returns></returns>
        public static IPathSearcher CreateSearcher()
        {
            return new ExactFilePathSearcher();
        }

        /// <summary>
        /// Creates an instance of file path searcher class by specifying searcher name.
        /// </summary>
        /// <param name="searcherName">Class name or display name of searcher.</param>
        /// <returns>
        /// An object of file path searcher class. If the searcher name is invalid,
        /// return an instance of default file path searcher class.
        /// </returns>
        public static IPathSearcher CreateSearcher(string searcherName)
        {
            if (IsDisplayName(searcherName))
            {
                searcherName = GetClassName(searcherName);
            }

            IPathSearcher searcher = null;
            switch (searcherName)
            {
                case ExactSearcherClassName:
                    searcher = new ExactFilePathSearcher();
                    break;

                case FuzzySearcherClassName:
                    searcher = new FuzzyFilePathSearcher();
                    break;

                case SubstringSearcherClassName:
                    searcher = new SubstringFilePathSearcher();
                    break;

                case ExtensionSearcherClassName:
                    searcher = new ExtensionFilePathSearcher();
                    break;

                case RegexSearcherClassName:
                    searcher = new RegexFilePathSearcher();
                    break;

                default:
                    searcher = CreateSearcher();
                    break;
            }

            return searcher;
        }

        /// <summary>
        /// Indicates whether the specified searcher name is a class name.
        /// </summary>
        /// <param name="name">A searcher name.</param>
        /// <returns>true if the the name is a class name; otherwise false.</returns>
        public static bool IsClassName(string name)
        {
            if (String.IsNullOrEmpty(name))
                return false;

            foreach (string aClassName in ClassNames)
            {
                if (aClassName.Equals(name))
                    return true;
            }

            return false;
        }

        /// <summary>
        /// Indicates whether the specified searcher name is a display name.
        /// </summary>
        /// <param name="name">A searcher name.</param>
        /// <returns>true if the name is a display name; otherwise false.</returns>
        public static bool IsDisplayName(string name)
        {
            if (String.IsNullOrEmpty(name))
                return false;

            foreach (string aDisplayName in DisplayNames)
            {
                if (aDisplayName.Equals(name))
                    return true;
            }

            return false;
        }

        /// <summary>
        /// Gets corresponding class name of a display name.
        /// </summary>
        /// <param name="displayName">A display name.</param>
        /// <returns>Corresponding class name.</returns>
        public static string GetClassName(string displayName)
        {
            if (displayName == null)
                return null;

            foreach (SearcherName aName in _searcherNames)
            {
                if (displayName.Equals(aName.DispalyName))
                    return aName.ClassName;
            }

            return null;
        }

        /// <summary>
        /// Gets corresponding display name of a class name.
        /// </summary>
        /// <param name="className">A class name.</param>
        /// <returns>Corresponding display name.</returns>
        public static string GetDisplayName(string className)
        {
            if (className == null)
                return null;

            foreach (SearcherName aName in _searcherNames)
            {
                if (className.Equals(aName.ClassName))
                    return aName.DispalyName;
            }

            return null;
        }

        /// <summary>
        /// Gets all class names.
        /// </summary>
        public static IEnumerable<string> ClassNames
        {
            get
            {
                foreach (SearcherName aName in _searcherNames)
                    yield return aName.ClassName;
            }
        }

        /// <summary>
        /// Gets all display names.
        /// </summary>
        public static IEnumerable<string> DisplayNames
        {
            get
            {
                foreach (SearcherName aName in _searcherNames)
                    yield return aName.DispalyName;
            }
        }

        /// <summary>
        /// Represents file searcher name.
        /// </summary>
        internal struct SearcherName
        {
            private string _className;
            private string _dispalyName;

            /// <summary>
            /// Initializes name of file searcher.
            /// </summary>
            /// <param name="className">The class name of searcher.</param>
            /// <param name="displayName">The display name of searcher.</param>
            public SearcherName(string className, string displayName)
            {
                _className = className;
                _dispalyName = displayName;
            }

            /// <summary>
            /// Gets name of class.
            /// </summary>
            public string ClassName
            {
                get { return _className; }
            }

            /// <summary>
            /// Gets name to be displayed.
            /// </summary>
            public string DispalyName
            {
                get { return _dispalyName; }
            }
        }
    }
}
